package cn.zzf.algs.note.base.collection.v1;

import java.util.Iterator;
import java.util.Spliterator;
import java.util.function.Consumer;

/**
 * @author GaoFeng
 * @date 2019/11/27 14:47
 */
public class LinkQueue<T> implements Queue<T>, Iterable<T> {

    /** 尾节点 */
    private Node last;

    /** 长度 */
    private int size;

    public LinkQueue() {

    }

    @Override
    public void enqueue(T element) {

        if (last == null) {
            // 设置首尾节点
            Node node = new Node(element, null);
            last = node;
            last.next = node;
        } else {
            // 在last节点后面添加node
            Node tailNode = last.next;
            last.next = new Node(element , tailNode);
        }

        size++;

    }

    @Override
    public T dequeue() {

        if (last == null) {
            return null;
        }

        Node first = last.next;

        if (first.next != null) {
            last.next = first.next;
        } else {
            last = null;
        }

        // 长度自增
        size--;
        return first.value;

    }



    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public Iterator<T> iterator() {
        return new Iterator<T>() {

            private Node currentNode = last;

            @Override
            public boolean hasNext() {
                return currentNode != null;
            }

            @Override
            public T next() {

                if (currentNode != null) {
                    Node next = currentNode.next;
                    currentNode.next = next.next;
                    return next.value;
                }

                return null;
            }

        };
    }

    @Override
    public void forEach(Consumer<? super T> action) {

    }

    @Override
    public Spliterator<T> spliterator() {
        return null;
    }

    private class Node {

        T value;
        Node next;

        Node(T value, Node next) {
            this.value = value;
            this.next = next;
        }

    }

}